package org.acm.seguin.refactor.type;
import java.io.File;
import java.util.LinkedList;
import java.util.StringTokenizer;
import org.acm.seguin.refactor.AddImportTransform;
import org.acm.seguin.refactor.ComplexTransform;
import org.acm.seguin.refactor.RemoveImportTransform;
import org.acm.seguin.refactor.TransformAST;
import org.acm.seguin.summary.FileSummary;
import org.acm.seguin.summary.ImportSummary;
import org.acm.seguin.summary.query.FileSummaryGetter;
import org.acm.seguin.summary.query.MovingTypeList;
import org.acm.seguin.summary.query.StayingTypeList;
/**
* Scans through the summary objects to create a list of files that reference
* a particular class.
*
*@author Chris Seguin
*/
public class MoveClassVisitor extends TypeChangeVisitor {
// Instance Variables
private String oldPackageName;
private String newPackageName;
private File base;
/**
* Determine if anything in this tree references these classes.
*
*@param oldPackage the name of the old package
*@param newPackage the name of the new package
*@param base the base directory
*@param complex Description of Parameter
*/
public MoveClassVisitor(String oldPackage, String newPackage, File base,
ComplexTransform complex) {
super(complex);
oldPackageName = oldPackage;
newPackageName = newPackage;
this.base = base;
}
/**
* Gets the File Specific Transform
*
*@param summary Gets a file specific transform
*@return The FileSpecificTransform value
*/
protected TransformAST getFileSpecificTransform(FileSummary summary) {
if (summary.isMoving()) {
return new ChangePackageTransform(newPackageName);
}
return null;
}
/**
* Gets the New Imports transform
*
*@param node the file summary
*@param className the name of the class that is changing
*@return The NewImports value
*/
protected AddImportTransform getNewImports(FileSummary node, String className) {
String currentPackage = "";
String otherPackage = "";
if (node.isMoving()) {
currentPackage = oldPackageName;
otherPackage = newPackageName;
}
else {
currentPackage = newPackageName;
otherPackage = oldPackageName;
}
return new AddImportTransform(currentPackage, className);
}
/**
* Gets the Remove Imports transform
*
*@param node the import summary
*@return The transform
*/
protected RemoveImportTransform getRemoveImportTransform(ImportSummary node) {
if (node.getType() == null) {
return null;
}
else {
return new RemoveImportTransform(oldPackageName, node.getType());
}
}
/**
* Gets the AppropriateClasses attribute of the TypeChangeVisitor object
*
*@param node Description of Parameter
*@return The AppropriateClasses value
*/
protected LinkedList getAppropriateClasses(FileSummary node) {
if (!node.isMoving()) {
MovingTypeList mtl = new MovingTypeList();
return mtl.query(oldPackageName);
}
else {
StayingTypeList stl = new StayingTypeList();
return stl.query(oldPackageName);
}
}
/**
* Gets the reference to the file where the refactored output should be sent
*
*@param node the files summary
*@return The NewFile value
*/
protected File getNewFile(FileSummary node) {
if (!node.isMoving()) {
return node.getFile();
}
File current = base;
StringTokenizer tok = new StringTokenizer(newPackageName, ".");
while (tok.hasMoreTokens()) {
current = new File(current, tok.nextToken());
}
return new File(current, node.getName());
}
/**
* Return the current package
*
*@return the current package of the class
*/
protected String getCurrentPackage() {
return oldPackageName;
}
/**
* Gets the RenamingTransform
*
*@param refactoring the refactoring
*@param node the file summary to reference
*@param className the name of the class that is changing
*/
protected void addRenamingTransforms(ComplexTransform refactoring,
FileSummary node, String className) {
String currentPackage = "";
String otherPackage = "";
if (node.isMoving()) {
currentPackage = oldPackageName;
otherPackage = newPackageName;
}
else {
currentPackage = newPackageName;
otherPackage = oldPackageName;
}
if (otherPackage.length() > 0) {
refactoring.add(new RenameTypeTransform(otherPackage, currentPackage, className));
}
}
/**
* Set the class name. Allows sub classes of this to reuse themselves for
* different classes in the same package.
*
*@param newClassName the new class name
*/
protected void add(String newClassName) {
FileSummary summary = (new FileSummaryGetter()).query(oldPackageName, newClassName);
if (summary != null) {
summary.setMoving(true);
}
else {
System.out.println("WARNING: Unable to find the class " + newClassName +
" in the package " + oldPackageName);
}
}
}